package de.fhaugsburg.games.boardgames;

import java.util.Set;


public class GridPoint implements Cloneable, Comparable<GridPoint>{

	private final int row, column;
	
	/**
	 * Constructs a new GridPoint
	 * @param row
	 * @param column
	 */
	public GridPoint(int row, int column) {
		this.row = row;
		this.column = column;
	}

	
	
	/**
	 * Dont know what this is doing :), negates 
	 * TODO
	 * @return
	 */
	public GridPoint neg(){
//		return new GridPoint(this.getColumn(), this.getRow());
		return new GridPoint(-this.getRow(), -this.getColumn());
	}
	
	
	/**
	 * @param delta
	 * @return
	 */
	public GridPoint plus(GridPoint delta){
		return new GridPoint (this.getRow() + delta.getRow(), this.getColumn() + delta.getColumn());
	}
	

	
	/**
	 * @param delta
	 * @return
	 */
	public GridPoint minus(GridPoint delta){
		return new GridPoint (this.getRow() - delta.getRow(), this.getColumn() - delta.getColumn());	
	}

	
	
	/**
	 * @param points
	 * @return
	 */
	public boolean isManhattanColinearWith (Set<GridPoint> points){
		
		if (points.isEmpty()) { // no element
			return true;
		}
		
		GridPoint[] gArray =  new GridPoint[points.size()];
		int i=0;
		
		for (GridPoint point : points) {
			gArray[i] = point;
			i++;
		}
		
		if (gArray.length == 1) { // 1 element
			if (ManhattanDirection.calcDir(this,gArray[0]) != null) {
				return true;
			}
			else {return false;}
		}
			
		ManhattanDirection manDir = ManhattanDirection.calcDir(gArray[0],gArray[1]);
		ManhattanDirection manDirInv = ManhattanDirection.calcDir(gArray[1],gArray[0]);
		ManhattanDirection tmp = ManhattanDirection.calcDir(this,gArray[0]);
			
		if ((tmp == manDir) || (tmp == manDirInv)) {
			return true;
		}
		
		return false;
	}
	


	/**
	 * @return the row
	 */
	public int getRow() {
		return row;
	}


	/**
	 * @return the column
	 */
	public int getColumn() {
		return column;
	}

	 
	
	/**
	 * toString
	 */
	@Override
	public String toString(){
		return "" + getRow() + ", " + getColumn();
	}
	

	/**
	 * Comparable
	 */
	public int compareTo(GridPoint o) {
		if (o instanceof GridPoint){ 	//obsolete -> Generics
			GridPoint g = (GridPoint) o;
			GridPoint comparePoint = this.minus(g);
			int compRow = comparePoint.getRow();
			int compCol = comparePoint.getColumn();
			if (compRow < 0){
				return -1;	//smaller
			}else if (compRow == 0){
				if (compCol < 0){
					return -1;
				}else if (compCol == 0){
					return 0;
				}else if (compCol > 0){
					return 1;
				}
			}else{
				return 1;	//bigger
			}
		}else{
			throw new RuntimeException();
		}
		return 0;
	}
	
	
	
	
	public boolean equals(Object o){
		if (o instanceof GridPoint){
			GridPoint g = (GridPoint) o;
			if (this.getRow() == g.getRow() && this.getColumn() == g.getColumn()){
				return true;
			}
		}
		return false;
	}
	
	
	
	
	/**
	 * clones this GridPoint
	 */
	public Object clone(){
		return new GridPoint(getRow(), getColumn());
	}
	
	
}
